from typing import List, Optional
import logging
from tortoise.exceptions import DoesNotExist, IntegrityError
from tortoise.transactions import atomic
from tortoise.functions import Count
from tortoise.expressions import Q
from app.models.warehouse_goods_models import WarehouseGoods
from app.models.warehouse_models import Warehouse
from app.models.goods_models import Goods
from app.schemas.warehouse_goods_schemas import WarehouseGoodsCreate, WarehouseGoodsUpdate
from app.services.base_service import BaseService

logger = logging.getLogger(__name__)

class WarehouseGoodsService(BaseService):
    """仓库商品服务类"""
    
    def __init__(self):
        super().__init__(WarehouseGoods)
        
    @classmethod
    async def check_warehouse_exists(cls, warehouse_id: int) -> bool:
        """检查仓库是否存在"""
        logger = logging.getLogger(f"{__name__}.{cls.__name__}")
        exists = await Warehouse.exists(id=warehouse_id)
        if not exists:
            logger.warning(f"仓库不存在: ID {warehouse_id}")
        return exists

    @classmethod
    async def check_goods_exists(cls, goods_id: int) -> bool:
        """检查商品是否存在"""
        exists = await Goods.exists(id=goods_id)
        if not exists:
            logger.warning(f"商品不存在: ID {goods_id}")
        return exists

    @classmethod
    @atomic()
    async def add_goods_to_warehouse(cls, data: WarehouseGoodsCreate) -> dict:
        """添加商品到仓库"""
        try:
            logger.info(f"开始添加商品到仓库: warehouse_id={data.warehouse_id}, goods_id={data.goods_id}")
            
            # 检查仓库是否存在
            if not await cls.check_warehouse_exists(data.warehouse_id):
                raise DoesNotExist(f"仓库不存在: ID {data.warehouse_id}")
            
            # 检查商品是否存在
            if not await cls.check_goods_exists(data.goods_id):
                raise DoesNotExist(f"商品不存在: ID {data.goods_id}")
            
            # 创建记录
            inventory = await WarehouseGoods.create(**data.model_dump())
            await inventory.fetch_related('warehouse', 'goods')
            
            logger.info(f"商品添加成功: inventory_id={inventory.id}")
            return {
                "id": inventory.id,
                "warehouse_id": inventory.warehouse_id,
                "warehouse_name": inventory.warehouse.name,
                # ... 其他字段 ...
            }
            
        except IntegrityError:
            logger.error(f"商品已存在于仓库: warehouse_id={data.warehouse_id}, goods_id={data.goods_id}")
            raise
        except Exception as e:
            logger.error(f"添加商品到仓库失败: {str(e)}", exc_info=True)
            raise

    @staticmethod
    async def update_inventory(inventory_id: int, update_data: WarehouseGoodsUpdate) -> Optional[dict]:
        """更新库存信息"""
        try:
            logger.info(f"开始更新库存: inventory_id={inventory_id}, update_data={update_data.model_dump()}")
            
            inventory = await WarehouseGoods.get_or_none(id=inventory_id)
            if not inventory:
                logger.warning(f"库存记录不存在: inventory_id={inventory_id}")
                return None

            # 验证数量关系
            final_min = update_data.min_quantity if update_data.min_quantity is not None else inventory.min_quantity
            final_max = update_data.max_quantity if update_data.max_quantity is not None else inventory.max_quantity
            final_quantity = update_data.quantity if update_data.quantity is not None else inventory.quantity

            if final_max < final_min:
                logger.error(f"数量验证失败: max_quantity({final_max}) < min_quantity({final_min})")
                raise ValueError("最大库存不能小于最小库存")

            # ... 更新逻辑 ...
            
            logger.info(f"库存更新成功: inventory_id={inventory_id}")
            return {
                "id": inventory.id,
                # ... 返回数据 ...
            }
            
        except ValueError as e:
            logger.error(f"库存更新数据验证失败: {str(e)}")
            raise
        except Exception as e:
            logger.error(f"更新库存失败: {str(e)}", exc_info=True)
            raise

    @staticmethod
    async def get_inventory(inventory_id: int) -> Optional[dict]:
        """获取单个库存记录详情"""
        try:
            logger.info(f"获取库存记录: inventory_id={inventory_id}")
            
            inventory = await WarehouseGoods.get_or_none(id=inventory_id).prefetch_related(
                'warehouse', 'goods'
            )
            
            if not inventory:
                logger.warning(f"库存记录不存在: inventory_id={inventory_id}")
                return None
                
            logger.debug(f"成功获取库存记录: inventory_id={inventory_id}")
            return {
                "id": inventory.id,
                # ... 返回数据 ...
            }
            
        except Exception as e:
            logger.error(f"获取库存记录失败: {str(e)}", exc_info=True)
            raise